Skip to content

test(token-2022/transfer-fee): assert fee config, balances and withheld amounts - #730

Open
moviendome wants to merge 2 commits into
solana-foundation:mainfrom
moviendome:test/token-2022-transfer-fee-assertions
Open

test(token-2022/transfer-fee): assert fee config, balances and withheld amounts#730
moviendome wants to merge 2 commits into
solana-foundation:mainfrom
moviendome:test/token-2022-transfer-fee-assertions

Conversation

@moviendome

Copy link
Copy Markdown
Contributor

Summary

tokens/token-2022/transfer-fee runs the full fee lifecycle — initialize, mint, two transfers, harvest, withdraw, update — but never reads anything back. Six specs log a transaction signature and the seventh mints and checks nothing, so the suite passes with the fee at zero, the cap ignored, or the whole transfer withheld. The spec titled "fee limit by maximumFee" does not look at maximumFee.

This reads the mint and token accounts after each step and asserts the numbers the fixture implies (decimals 2, 100 bps, maximumFee = 1, 300 minted):

  • after initialize: both authorities are the payer, withheldAmount is 0, older and newer fee are 100 bps / max 1
  • after mint: sender holds 300
  • after transfer 100: sender 200, recipient 99, recipient withheld 1
  • after transfer 200: sender 0, recipient 298, recipient withheld 2 — 1% would be 2, the cap holds it to 1
  • after harvest: recipient withheld 0, mint withheldAmount 2
  • after withdraw: mint withheldAmount 0, sender holds 2
  • after update to 0/0: newer fee is 0 bps / max 0 at epoch + 2, older fee still 100 bps / max 1

Reads use getMint, getAccount, getTransferFeeConfig and getTransferFeeAmount from the @solana/spl-token version already in the dependency set. No new dependencies; lockfile unchanged. Test bodies and the existing log lines are untouched; the assertions are appended to each spec.

Test plan

  • anchor test at this commit: 7 passing.
  • Red proof: set maximumFee to 3 in the initialize spec and rerun. The first transfer still passes (the cap is not reached at 100), then 4 failing: the cap spec (expected 297n to equal 298n), harvest and withdraw (3n vs 2n), and update (3n vs 1n). Restored to 1, back to 7 passing.
  • pnpm check (prettier) clean.

AI use

I identified the gap while reading this example, chose the assertions and the expected numbers, and reviewed the diff and both test runs; Claude drafted the code and this description.

🤖 Generated with Claude Code

…ld amounts

The suite runs the full fee lifecycle but never reads anything back: six
specs log a signature and the seventh mints and checks nothing, so it
would pass with the fee at zero, the cap ignored, or the whole transfer
withheld. Read the mint and token accounts after each step and assert
the numbers the fixture implies: the TransferFeeConfig after initialize,
sender and recipient balances and withheld amounts after each transfer
(the second proving maximumFee caps 1% of 200 at 1), the withheld amount
moving to the mint on harvest and to the sender's account on withdraw,
and the updated fee scheduled two epochs out with the old one still in
force. Reads use @solana/spl-token helpers already in the dependency set.
@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge, although the existing non-blocking epoch-rollover finding remains only partially addressed.

Summary

  • Verifies fee configuration and authorities after initialization.
  • Checks sender, recipient, and withheld balances after minting and transfers.
  • Confirms the maximum-fee cap, harvest, withdrawal, and fee-schedule update behavior.
  • Attempts to make the activation-epoch assertion resilient to an epoch rollover.

Reviews (2) · Last reviewed commit: "test(token-2022/transfer-fee): read the ..."

Comment thread tokens/token-2022/transfer-fee/anchor/tests/transfer-fee.ts Outdated
…e update

The activation epoch was compared against an epoch read after the
transaction, which could roll over between execution and the read.
Read it before and after and accept either, so the assertion cannot
flake on an epoch boundary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant